package org.example.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.jsonwebtoken.SignatureAlgorithm;
import org.example.dto.LoginDto;
import org.example.model.LoginUserDetails;
import org.example.provider.CustomDaoAuthenticationProvider;
import org.example.service.SysLoginService;
import org.example.utils.JwtUtils;
import org.example.utils.Redisconstant;
import org.example.utils.ResponseResult;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author Rommel
 * @version 1.0
 * @date 2023/6/14-18:30
 * @description TODO
 */
@Service
public class SysLoginServiceImpl implements SysLoginService {

    @Resource
    private UserDetailsServiceImpl userDetailsServiceImpl;
    @Resource
    public RedisTemplate redisTemplate;



    @Override
    public ResponseResult login(LoginDto loginDto) {

        //传入用户名和密码构建UsernamePasswordAuthenticationToken
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken(loginDto.getUsername(),loginDto.getPassword());
        //交给AuthenticationManager进行认证
        CustomDaoAuthenticationProvider customDaoAuthenticationProvider = new CustomDaoAuthenticationProvider(userDetailsServiceImpl,new BCryptPasswordEncoder());
        Authentication authenticate = null;
        try {
            authenticate = customDaoAuthenticationProvider.authenticate(usernamePasswordAuthenticationToken);
        } catch (RuntimeException e) {
            return ResponseResult.fail(e.getMessage());
        }
        //判断是否认证通过
        if (Objects.isNull(authenticate)){
            return ResponseResult.fail("登录失败");
        }
        LoginUserDetails loginUserDetails = (LoginUserDetails)authenticate.getPrincipal();
        //token有效期
        Long expiration = System.currentTimeMillis() + 1000 * 60 * 60 * 2;
        //认证通过，返回jwt-token
        String jwtToken = JwtUtils.createJwt(String.valueOf(IdWorker.getId())
                ,loginUserDetails.getUsername()
                ,new Date(expiration)
                ,SignatureAlgorithm.HS512
                ,JwtUtils.base64EncodedSecretKey
        );
        redisTemplate.opsForValue().set(Redisconstant.LOGIN_SYS_USER_TOKEN_WEB_KEY+loginUserDetails.getUserid(),jwtToken,expiration, TimeUnit.MILLISECONDS);
        return ResponseResult.ok(jwtToken);
    }

    @Override
    public ResponseResult loginOut() {

        LoginUserDetails loginUserDetails = (LoginUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String key = Redisconstant.LOGIN_SYS_USER_TOKEN_WEB_KEY+loginUserDetails.getUserid();
        redisTemplate.delete(key);

        return ResponseResult.ok("退出成功");
    }
}
